package com.ayoldi.podcastusbsync.synchronizer;

import java.io.File;
import java.io.FilenameFilter;
import java.math.BigInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.filechooser.FileSystemView;

import jmtp.PortableDevice;
import jmtp.PortableDeviceFolderObject;
import jmtp.PortableDeviceManager;
import jmtp.PortableDeviceObject;
import jmtp.PortableDeviceStorageObject;

import org.apache.log4j.Logger;

public class USBDeviceSynchronizerUtils {

	static Logger LOG = Logger.getLogger(USBDeviceSynchronizerUtils.class);
	public static final Pattern VOLUME_LABEL_REGEX=Pattern.compile("(.*)\\s+\\([A-Za-z]+\\:\\)");
	
	public static String getVolumeLabel (File file){
		String temp=FileSystemView.getFileSystemView().getSystemDisplayName (file);
		Matcher m=VOLUME_LABEL_REGEX.matcher(temp);
		if (m.matches()){
			return m.group(1);
		}
		return null;
	}
	
	public static class PartialDownloadsFileFilter implements FilenameFilter {

		public boolean accept(File dir, String name) {
			if (name.endsWith(".part")){
				return false;
			}
			return true;
		}
		
		
		
	}
	
//	public static boolean copyFileMTP(File orig, File dest, String deviceId){
//		DeviceManager dm = null;
//		boolean success=false;
//		try {
//			dm = DeviceManager.getInstance();
//			dm.createInstance();
//			dm.scanDevices();
//			dm.dump();
//			Iterator it = dm.getDeviceList().keySet().iterator();
//			while (it.hasNext()){
//				String devkey = (String)it.next();
//				UsbDevice usbdev = (UsbDevice)dm.getDeviceList().get(devkey);
//				if (usbdev.getSerial().equals(deviceId)){
//					long folderExists=usbdev.existFolder(dest.getParent()+"\\");
//					
//					IDeviceTransferNotifier notifier=new IDeviceTransferNotifier() {
//                        public void notifyBegin(long l) {
//                            System.out.print("påbörjar överföring... ");
//                        }
//                        public void notifyCurrent(long l) {
//                            System.out.print(l);
//                        }
//                        public void notifyEnd() {
//                            System.out.println("Avslutar överföring!");
//                        }
//                        public boolean getAbort() {
//                            return false;
//                        }
//                    };
//					long result=usbdev.sendFile(orig.getAbsolutePath(),dest.getPath() ,notifier, null);
//					if (result!=-1){
//						return true;
//					}
//				}
//			}
//			return success;
//			
//			
//		} catch (Throwable e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//			return success;
//		}	
//		finally{
//			if (dm!=null){
//				dm.releaseInstance();
//			}
//		}
//		
//	}
	
	public static String searchOnMTPDevicesByDeviceName(String deviceName){
//		DeviceManager dm = null;
//		try {
//			dm = DeviceManager.getInstance();
//			dm.createInstance();
//			dm.scanDevices();
//			dm.dump();
//			Iterator it = dm.getDeviceList().keySet().iterator();
//			while (it.hasNext()){
//				String devkey = (String)it.next();
//				UsbDevice usbdev = (UsbDevice)dm.getDeviceList().get(devkey);
//				if (deviceName.equals(usbdev.getName())){
//					return usbdev.getSerial();
//				}
//				
//			}
//			return null;
//			
//			
//		} catch (Throwable e) {
//			e.printStackTrace();
//			return null;
//		}		
//		finally{
//			if (dm!=null){
//				dm.releaseInstance();
//			}
//		}
		
		return null;
	}
	

	public static String searchOnMTPDevicesByFilename(String fileName){
		PortableDeviceManager manager = new PortableDeviceManager();
		for(PortableDevice device : manager) {
			device.open();
			String sn=device.toString();

			for(PortableDeviceObject object : device.getRootObjects()) {
				LOG.debug("Object: "+object.getName());
				if (object instanceof PortableDeviceStorageObject){
					PortableDeviceStorageObject storage = (PortableDeviceStorageObject)object;
					PortableDeviceObject[] objects= storage.getChildObjects();
					for (PortableDeviceObject currentObject : objects){
						String name=currentObject.getName();
						String originalFilename=currentObject.getOriginalFileName();
						
						if (name.equals(fileName)){
							return sn;
						}
					}
					
					
				}
			}
		}
		return null;

	}
	
	public static boolean copyFileMTP(File orig, File dest, String deviceId){
		PortableDeviceManager manager = new PortableDeviceManager();
		for(PortableDevice device : manager) {
			device.open();
			String sn=device.toString();
			if (sn!=null && sn.equals(deviceId)){
				for(PortableDeviceObject object : device.getRootObjects()) {
			        LOG.debug("Object: "+object.getName());
			        if (object instanceof PortableDeviceStorageObject){
			        	PortableDeviceStorageObject storage = (PortableDeviceStorageObject)object;
			        	String completePath=dest.getParent();
			        	if (completePath.startsWith(File.separator)){
			        		completePath=completePath.substring(1);
			        	}
			        	if (completePath.endsWith(File.separator)){
			        		completePath=completePath.substring(0,completePath.length()-1);
			        	}
			        	String paths[]=completePath.split("\\"+File.separator);
			        	PortableDeviceObject[] rootFolders=storage.getChildObjects();
			        	PortableDeviceFolderObject lastParent=null;
			        	
			        	int depth=0;
			        	while (depth<paths.length){
			        		boolean found=false;
			        		for (PortableDeviceObject currentFolder : rootFolders){
			        			String folderName=currentFolder.getOriginalFileName();
			        			if (folderName.equals(paths[depth]) && currentFolder instanceof PortableDeviceFolderObject){
			        				PortableDeviceFolderObject currentFolder2=(PortableDeviceFolderObject)currentFolder;
			        				depth++;
			        				rootFolders=currentFolder2.getChildObjects();
			        				lastParent=currentFolder2;
			        				found=true;
			        				break;
			        			}
			        		}
			        		if (found){
			        			continue;
			        		}
			        		// EL DIRECTORIO NO EXISTE!			        		
			        		else{
			        			PortableDeviceFolderObject newDir=null;
			        			if (lastParent!=null){
			        				newDir=lastParent.createFolderObject(paths[depth]);
			        			}
			        			else{
			        				newDir=storage.createFolderObject(paths[depth]);
			        			}
			        						        			
			        			if (newDir!=null){
			        				depth++;
			        				rootFolders=newDir.getChildObjects();
			        				lastParent=newDir;
			        			}
			        			else{
			        				return true;
			        			}
			        		}
			        	}
			        	if (depth==paths.length){
			        		// MIRAR PRIMERO SI EL FICHERO EXISTE
			        		boolean fileAlreadyExists=false;
			        		boolean isSameSize=false;
			        		PortableDeviceObject existingFileFound=null;
			        		PortableDeviceObject[] childs=lastParent.getChildObjects();
			        		for (PortableDeviceObject child : childs){
			        			if (! (child instanceof PortableDeviceFolderObject)){
			        				if (child.getOriginalFileName().equalsIgnoreCase(orig.getName())){			        					
			        					BigInteger sizeDev=child.getSize();
			        					BigInteger sizeHDD=BigInteger.valueOf(orig.length());
			        					existingFileFound=child;
			        					if (child.getSize().equals(BigInteger.valueOf(orig.length()))){
			        						isSameSize=true;
			        					}
			        					fileAlreadyExists=true;
			        					break;
			        				}
			        			}
			        		}
			        		if (fileAlreadyExists && isSameSize){
			        			LOG.debug("File '"+orig.getAbsolutePath()+"' already exists on destination device with same size, skipping!");
			        			return true;
			        		}
			        		else if (fileAlreadyExists && !isSameSize){
			        			LOG.debug("File '"+orig.getAbsolutePath()+"' already exists on destination device with different size, overwritting!");
			        			existingFileFound.delete();
			        		}
			        		try {
								lastParent.addAudioObject(orig, "", "", BigInteger.ZERO);
							} catch (Exception e) {
								e.printStackTrace();
								return false;
							} 
			        		return true;
			        	}
			        	

			        }
				}
			}
			
			
			
		}
		return false;
		
	}

	
	
}
